﻿using System.Linq;
using PTop.Application.Biz;
using PTop.Application.SystemSecurity;
using PTop.Code;
using PTop.Domain.Entity.Article;
using PTop.Domain.IRepository.Article;
using PTop.Repository.Article;
using System;
using System.Collections.Generic;

namespace PTop.Application.Article
{
    /// <summary>
    /// ArticleApp
    /// </summary>	
    public class ArticleApp
    {
        private IArticleRepository service = new ArticleRepository();

        /// <summary>
        /// 查询文章
        /// </summary>
        /// <param name="pagination"></param>
        /// <param name="keyword">关键词</param>
        /// <param name="type">类别。-1=所有,1=首页,2＝IC卡,3=新闻动态,4=先进</param>
        /// <param name="state">审核状态。-1=所有,0=未发布，1=发布, 2=失效</param>
        /// <param name="isTop"></param>
        /// <returns></returns>
        public List<ArticleEntity> GetList(Pagination pagination, string keyword, int type, int state, int isTop)
        {
            var expression = ExtLinq.True<ArticleEntity>();
            if (!string.IsNullOrEmpty(keyword))
            {
                expression = expression.And(t => t.F_Title.Contains(keyword));
                expression = expression.Or(t => t.F_Content.Contains(keyword));
                expression = expression.Or(t => t.F_CreatorUserId.Contains(keyword));
            }
            if (type != -1)
            {
                expression = expression.And(t => t.F_Type == type);
            }
            if (state != -1)
            {
                expression = expression.And(t => t.F_State == state);
            }
            if (isTop != -1)
            {
                expression = isTop == 1 ? expression.And(t => t.F_IsTop) : expression.And(t => !t.F_IsTop);
            }
            expression = expression.And(t => t.F_DeleteMark != true);
            return service.FindList(expression, pagination);
        }

        public ArticleEntity GetForm(string keyValue)
        {
            return service.FindEntity(keyValue);
        }
        public void Delete(string keyValue)
        {
            var entity = GetForm(keyValue);
            service.Delete(entity);
            new LogApp().WriteDbLog("文章管理", DbLogType.Delete, string.Format("Id:{0},Title:{1}", entity.F_Id, entity.F_Title));
        }
        public void Update(ArticleEntity entity)
        {
            service.Update(entity);
        }
        public void SubmitForm(ArticleEntity entity, string keyValue)
        {
            if (!string.IsNullOrEmpty(keyValue))
            {
                //发布状态
                var oldEntity = service.FindEntityWithNoTracking(m => m.F_Id == keyValue);
                if (oldEntity != null && oldEntity.F_State != entity.F_State)
                {
                    if (entity.F_State == 1)
                    {
                        entity.F_ReleaseTime = DateTime.Now;
                    }
                    else if (entity.F_State == 2)
                    {
                        entity.F_ReleaseTime = null;
                    }
                }
                entity.Modify(keyValue);
                service.Update(entity);
                new LogApp().WriteDbLog("文章管理", DbLogType.Update, string.Format("Id:{0},Title:{1}", entity.F_Id, entity.F_Title));
            }
            else
            {
                entity.Create();
                //发布状态
                if (entity.F_State == 1)
                {
                    entity.F_ReleaseTime = DateTime.Now;
                }
                else if (entity.F_State == 2)
                {
                    entity.F_ReleaseTime = null;
                }
                service.Insert(entity);
                new UserStatisticsApp().AddCount("F_ArticleCount");
                new LogApp().WriteDbLog("文章管理", DbLogType.Create, string.Format("Id:{0},Title:{1}", entity.F_Id, entity.F_Title));
            }
        }

        /// <summary>
        /// 审核
        /// </summary>
        /// <param name="keyValue"></param>
        /// <param name="state"></param>
        public void Audit(string keyValue, int state)
        {
            var entity = service.FindEntity(keyValue);
            entity.Modify(keyValue);
            entity.F_State = state;
            if (state == 1)
            {
                entity.F_ReleaseTime = DateTime.Now;
            }
            else if (state == 2)
            {
                entity.F_ReleaseTime = null;
            }
            service.Update(entity);
            new LogApp().WriteDbLog("文章管理", DbLogType.Update, string.Format("Id:{0},Title:{1},F_State为:{2}", entity.F_Id, entity.F_Title, state));
        }


        #region For front

        private static readonly object Lock = 1;
        private static readonly object Lock1 = 1;
        private static readonly object Lock2 = 1;

        public ArticleEntity GetArticle(string keyValue)
        {
            string cacheKey = "Article_" + keyValue;
            var article = CacheFactory.Cache().GetCache<ArticleEntity>(cacheKey);
            if (article == null)
            {
                lock (Lock)
                {
                    article = CacheFactory.Cache().GetCache<ArticleEntity>(cacheKey);
                    if (article == null)
                    {
                        article = service.FindEntity(keyValue);
                        CacheFactory.Cache().WriteCache(article, cacheKey, DateTime.Now.AddMinutes(10));
                    }
                }
            }
            return article;
        }

        /// <summary>
        /// 根据类别获取单篇文章
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public ArticleEntity GetArticleByType(int type)
        {
            string cacheKey = "ArticleByType" + type;
            var articleType = CacheFactory.Cache().GetCache<ArticleEntity>(cacheKey);
            if (articleType == null)
            {
                lock (Lock1)
                {
                    articleType = CacheFactory.Cache().GetCache<ArticleEntity>(cacheKey);
                    if (articleType == null)
                    {
                        articleType = service.FindEntity(m => m.F_Type == type && m.F_State == 1);
                        CacheFactory.Cache().WriteCache(articleType, cacheKey, DateTime.Now.AddMinutes(10));
                    }
                }
            }
            return articleType;
        }

        /// <summary>
        /// 查询文章
        /// </summary>
        /// <param name="pageIndex"></param>
        /// <param name="type">类别</param>
        /// <param name="isTop"></param>
        /// <returns></returns>
        public List<ArticleEntity> GetList(int pageIndex, int type, bool isTop = false)
        {

            string cacheKey = string.Format("ArticleList_{0}_{1}_{2}", pageIndex, type, isTop);
            var list = CacheFactory.Cache().GetCache<List<ArticleEntity>>(cacheKey);
            if (list == null)
            {
                lock (Lock2)
                {
                    list = CacheFactory.Cache().GetCache<List<ArticleEntity>>(cacheKey);
                    if (list == null)
                    {
                        var expression = ExtLinq.True<ArticleEntity>();
                        expression = expression.And(t => t.F_Type == type);
                        expression = expression.And(t => t.F_State == 1);
                        expression = isTop ? expression.And(t => t.F_IsTop) : expression.And(t => !t.F_IsTop);
                        expression = expression.And(t => t.F_DeleteMark != true);
                        var pagination = new Pagination
                        {
                            page = pageIndex,
                            rows = 8,
                            sidx = "F_ReleaseTime desc",
                            sord = "asc"
                        };
                        list = service.FindList(expression, pagination);
                        if (isTop)
                        {
                            var listTemp = new List<ArticleEntity>();
                            listTemp.AddRange(list.Where(m => m.F_Order > 0).OrderBy(m => m.F_Order));
                            listTemp.AddRange(list.Where(m => m.F_Order <= 0).OrderByDescending(m => m.F_ReleaseTime));
                            list = listTemp;
                        }
                        CacheFactory.Cache().WriteCache(list, cacheKey, DateTime.Now.AddMinutes(10));
                    }
                }
            }
            return list;
        }

        public void UpdateNumber(string type, string articleId)
        {
            service.UpdateNumber(type, articleId);
        }
        #endregion

    }
}